namespace BM.Tools.WebControls.MForm.Controls.Helper
{
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;    
    using System.Linq;
    using System.Web.UI.WebControls;

    /// <summary>
    /// A class that makes managing webcontrols css classes easier
    /// </summary>
    public class CssClasses : ICollection<string>
    {                
        private readonly Collection<string> classes = new Collection<string>();

        /// <summary>
        /// Initializes a new instance of the <see cref="CssClasses"/> class. 
        /// </summary>
        /// <param name="owner">
        /// The owner.
        /// </param>
        public CssClasses(WebControl owner)
        {
            Owner = owner;
            Add(Owner.CssClass);
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="CssClasses"/> class. 
        /// </summary>
        /// <param name="owner">
        /// The owner.
        /// </param>
        /// <param name="classes">
        /// The classes.
        /// </param>
        public CssClasses(WebControl owner, params string[] classes) : this(owner)
        {
            Add(classes);
        }

        /// <summary>
        /// Gets classes count.
        /// </summary>
        public int Count
        {
            get
            {
                return classes.Count;
            }
        }

        /// <summary>
        /// Gets a value indicating whether is read only.
        /// </summary>
        public bool IsReadOnly
        {
            get
            {
                return false;
            }
        }

        /// <summary>
        /// Gets Owner.
        /// </summary>
        public WebControl Owner
        {
            get;
            private set;
        }

        /// <summary>
        /// returns the css class with the specified index
        /// </summary>
        /// <param name="index">
        /// The index.
        /// </param>
        public string this[int index]
        {
            get
            {
                return classes[index];
            }

            set
            {
                classes[index] = value;
                Owner.CssClass = ToString();
            }
        }

        /// <summary>
        /// Adds an array of css classes
        /// </summary>
        /// <param name="cssClasses">
        /// The css classes
        /// </param>
        public void Add(params string[] cssClasses)
        {
            if (cssClasses == null)
            {
                return;
            }

            foreach (string cls in cssClasses)
            {
                AddSingle(cls.Trim());
            }
        }

        /// <summary>
        /// Adds css classes defined in one string
        /// </summary>
        /// <param name="item">
        /// The cssClasses.
        /// </param>
        public void Add(string item)
        {
            if (item == null)
            {
                return;
            }

            Add(item.Split(' '));
        }

        /// <summary>
        /// Adds a single css class
        /// </summary>
        /// <param name="cssClass">
        /// The cssClass.
        /// </param>
        public void AddSingle(string cssClass)
        {
            if (!Contains(cssClass) && !string.IsNullOrEmpty(cssClass))
            {
                classes.Add(cssClass);
                Owner.CssClass = ToString();
            }
        }

        /// <summary>
        /// Clears css classes from the webcontrol
        /// </summary>
        public void Clear()
        {
            classes.Clear();
            Owner.CssClass = ToString();
        }

        /// <summary>
        /// seacrches for the specified css class
        /// </summary>
        /// <param name="item">
        /// The css class.
        /// </param>
        /// <returns>
        /// is the css class in the collection
        /// </returns>
        public bool Contains(string item)
        {
            return classes.Contains(item);
        }

        /// <summary>
        /// Copies the css classes collection to a specified array
        /// </summary>
        /// <param name="array">
        /// The array.
        /// </param>
        /// <param name="arrayIndex">
        /// The array index.
        /// </param>
        public void CopyTo(string[] array, int arrayIndex)
        {
            classes.CopyTo(array, arrayIndex);
        }

        /// <summary>
        /// returns the css classes enumerator
        /// </summary>
        /// <returns>
        /// the enumerator
        /// </returns>
        public IEnumerator<string> GetEnumerator()
        {
            return classes.GetEnumerator();
        }

        /// <summary>
        /// returns the index of the specified css class
        /// </summary>
        /// <param name="item">
        /// The css class.
        /// </param>
        /// <returns>
        /// the index of the specified css class or -1
        /// </returns>
        public int IndexOf(string item)
        {
            return classes.IndexOf(item);
        }

        /// <summary>
        /// removes the specified css class
        /// </summary>
        /// <param name="item">
        /// The css class.
        /// </param>
        /// <returns>
        /// was the css class removed
        /// </returns>
        public bool Remove(string item)
        {
            if (classes.Remove(item))
            {
                Owner.CssClass = ToString();
                return true;
            }

            return false;
        }

        /// <summary>
        /// returns the string representation of the css classes
        /// </summary>
        /// <returns>
        /// the css classes as string
        /// </returns>
        public override sealed string ToString()
        {
            return string.Join(" ", classes.ToArray());
        }

        /// <summary>
        /// returns the enumerator
        /// </summary>
        /// <returns>
        /// the enumerator over css classes
        /// </returns>
        IEnumerator IEnumerable.GetEnumerator()
        {
            return GetEnumerator();
        }
    }
}